package com.apes.autoparts.parts.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.autoparts.parts.model.*;
import com.apes.autoparts.parts.repository.*;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.mq.MQUtil;
import com.apes.framework.util.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("queryPartsService")
public class QueryPartsService extends DomainService {

    @Autowired
    private ApiAutoParts91Service apiService;

    @Autowired
    private SubGroupRepository subGroupRepository;

    @Autowired
    private PartRepository partRepository;

    @Autowired
    private AutoModelRepository autoModelRepository;

    @Autowired
    private MainGroupRepository mainGroupRepository;

    @Autowired
    private SequenceService sequenceService;


    /***
     * 查询零件
     * @param request
     * @return
     */
    public JSONArray queryParts(SimpleRequest request) {

        JSONObject param = request.getJO();
        param.remove("PZCXID");
        param.remove("QCCPMC");
        JSONArray jsonArray = apiService.queryPartsWithSubGroup(param);
        jsonArray = jsonArray.stream().filter(json -> {
            JSONObject item = (JSONObject) json;
            return ((JSONObject) json).getBooleanValue("belongToVin");
        }).collect(Collectors.toCollection(JSONArray::new));

        if (jsonArray.size() == 0)
            throw new RuntimeException("没有找到输入该车型的配件");
        return combinationPartsData(param, jsonArray, request);
    }



    /***
     * 处理返回值
     */
    private List<Part> handleResponse(JSONArray param) {
        List<Part> parts = new ArrayList<>();
        if (param == null) return parts;

        /***
         * 处理逻辑
         */
        for (int i = 0; i < param.size(); i++) {
            Part part  = new Part();
            part.setBrandName(param.getJSONObject(i).getString("brandName"));
            part.setImageSN(param.getJSONObject(i).getString("imageSN"));


            part.setQuantity(param.getJSONObject(i).getString("quantity"));
            part.setNote(param.getJSONObject(i).getString("notes"));
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");

            // 空置转化异常
            if (param.getJSONObject(i).getDouble("cost") != null)
                part.setCost(param.getJSONObject(i).getDouble("cost"));
            if (param.getJSONObject(i).getString("priceUpdatedAt") != null) {
                try {
                    Date priceUpdatedAt = sf.parse(param.getJSONObject(i).getString("priceUpdatedAt"));
                    part.setPriceUpdatedAt(priceUpdatedAt);
                } catch (Exception e) {
                    throw new RuntimeException("时间转化失败" + e);
                }
            }
            if (param.getJSONObject(i).getDouble("price") != null)
                part.setPrice(param.getJSONObject(i).getDouble("price"));

            part.setReplacedPartCodes(param.getJSONObject(i).getString("replacedPartCodes"));
            part.setBelongToVin(param.getJSONObject(i).getBoolean("belongToVin"));
            part.setPartCode(param.getJSONObject(i).getString("partCode"));
            part.setPartName(param.getJSONObject(i).getString("partName"));
//            part.setId(sequenceService.getId(Part.CONST_TABLE_NAME));
            part.setPartId(param.getJSONObject(i).getString("id"));
            part.setBrandCode(param.getJSONObject(i).getString("brandCode"));
            part.setMarketCode(param.getJSONObject(i).getString("marketCode"));
            part.setMarketName(param.getJSONObject(i).getString("marketName"));
            part.setTimestamp(new Date());
            parts.add(part);
        }
        return parts;
    }

    public List<Part> queryPartsAll(SimpleRequest request) {

        JSONObject param = request.getJO();

        // 确认是否已经被解析过
        List<Part> parts = partRepository.findAll(
                JpaDsl.toCriteriaByEq(
                        "subGroupId.id", param.getString("id")
                )
        );

        if (parts.size() != 0) return parts;


        // 进行查询
//        SubGroup subGroup = subGroupRepository.findOne(param.getString("id"));
//        param.put("id", subGroup.getSubGroupId());

//        {
//            "vin":"LHGCP168288027506",
//                "brandCode":"honda",
//                "id":"3945",
//                "selectorId":"10135"
//        }

        // 获取配件信息
        SubGroup subGroup = subGroupRepository.findOne(param.getString("id"));
        AutoModel autoModel = autoModelRepository.findOne(param.getString("selectorId"));
        param.put("id", subGroup.getSubGroupId());
        param.put("selectorId", autoModel.getSelectorId());
        JSONArray response = apiService.queryPartsWithSubGroup(param);
        List<Part> partList = handleResponse(response);

        // 保存配件
        partList.forEach(part -> {
            part.setMainGroupId(subGroup.getMainGroupId());
            part.setSubGroupId(subGroup);
            part.setOrgSelectorId(autoModel);
            partRepository.saveAndFlush(part);
        });
        return partList;
    }


    /**
     * 查询配件信息
     * @param param
     * @return
     */
    public List<Part> queryParts(JSONObject param) {

        JSONArray response = apiService.queryPartsWithSubGroup(param);
        List<Part> partList = handleResponse(response);

        return partList;
    }

    /**
     * 查询配件(模糊查询)
     * @param request
     * @return
     */
    public JSONObject fuzzyQueryOfParts(SimpleRequest request) {
        JSONObject param = request.getJO();
        JSONObject response = apiService.fuzzyQueryOfParts(param);
        if (response == null)
            response = new JSONObject();
        return response;
    }


    /**
     * 查询配件(模糊查询)
     * @param request
     * @return
     */
    public JSONObject fuzzyOfParts(SimpleRequest request) {
        List<Map> filters = request.get("condition");
        JSONObject param = new JSONObject();
        JSONObject response = null;
        JSONObject category = null;
        Boolean isQuery = true;
        String partName = "";       // 用户输入关键词
        String categoryName = "";  // 标准配件名称
        for (Map filter : filters) {
            if ("dataCenterCondition".equals(filter.get("field"))) {
                param = JSONObject.parseObject(filter.get("value").toString());
                partName = param.getString("keywords");
            }
            if ("isQuery".equals(filter.get("field"))) isQuery = Boolean.valueOf(filter.get("value").toString());
            if ("searchContent".equals(filter.get("field"))) {
                category = (JSONObject) filter.get("value");
                if (category.getString("partsTagName") == null || "".equals(category.getString("partsTagName")))
                    categoryName = null;
                else {
                    categoryName = category.getString("partsTagName");
                }
            }
        }
        if (!isQuery && category.getJSONObject("partsTag").get("filterCondition") == null) {
            response = new JSONObject();
            response.put("items", new ArrayList<>());
            response.put("display", true);
            return response;
        }

        String PZCXID = param.getString("PZCXID");
        String QCCPMC = param.getString("QCCPMC");
        // 去除部分参数，预防有多参数第三接口报错问题
        param.remove("PZCXID");
        param.remove("QCCPMC");
        response = getZPData(partName, categoryName, param, PZCXID, QCCPMC, request);
        response.put("display",
                category != null ?( category.getJSONObject("partsTag").get("filterCondition") != null ?
                        category.getJSONObject("partsTag").getJSONObject("filterCondition").getJSONObject("smartAccessoriesConfig").getIntValue("smartAccessoriesConfig") == 0 :
                true) : true);
        return response;
    }

    /**
     * 通过OE号获取品牌件信息
     * @param request
     * @return
     */
    public JSONObject queryBrandParts(SimpleRequest request) {
        JSONObject param = request.getJO();
        JSONObject response = apiService.queryBrandParts(param);
        if (response == null)
            response = new JSONObject();
        return response;
    }

    public JSONObject queryPartsSimple(SimpleRequest request) {
        JSONObject param = request.getJO();
        JSONObject response = apiService.queryPartsSimple(param);
        if (response == null)
            response = new JSONObject();
        return response;
    }

    public JSONObject searchParts(SimpleRequest request) {
        JSONObject param = request.getJO();
        JSONObject response = apiService.searchParts(param);
        if (response == null)
            response = new JSONObject();
        return response;
    }

    public JSONObject searchPartsByVinKeywords(SimpleRequest request) {
        JSONObject param = request.getJO();
        JSONObject response = apiService.searchPartsByVinKeywords(param);
        if (response == null)
            response = new JSONObject();
        return response;
    }


    public JSONArray combinationPartsData(JSONObject param, JSONArray jsonArray, SimpleRequest request) {
        if (jsonArray == null || jsonArray.size() == 0)
            jsonArray = new JSONArray();


        //  oe所对应的配件名称
        param = request.getJO();

        JSONArray jsonArray1 = new JSONArray();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject josn = new JSONObject();
            if (jsonArray.getJSONObject(i).getString("partCode") == null )
                continue;
            josn.put("partCode", jsonArray.getJSONObject(i).getString("partCode"));
            josn.put("PZCXID", param.getString("PZCXID"));
            josn.put("partName", jsonArray.getJSONObject(i).getString("partName"));
            josn.put("QCCPMC", param.getString("QCCPMC"));
            jsonArray1.add(josn);
        }
        if (jsonArray1.size() == 0)
            return new JSONArray();

        /**
         * 获取oe所对应的配件名称
         */
        JSONArray tempArray = SpringManager.getBean(PartDao.class).queryCategories(jsonArray1);
        Map<String, List> parts = new HashMap();

        /**
         * 配件名称数据处理JSONArray 转成 key,value
         */
        for (int i = 0; i < tempArray.size(); i++) {
            List<JSONObject> listPart = new ArrayList();
            if (parts.get(tempArray.getJSONObject(i).getString("PARTNUMBER")) == null ) {
                JSONObject json = new JSONObject();
                json.put("PJMCID", tempArray.getJSONObject(i).getString("PJMCID"));
                json.put("PJMC", tempArray.getJSONObject(i).getString("PJMC"));
                listPart.add(json);
                parts.put(tempArray.getJSONObject(i).getString("PARTNUMBER"), listPart);
            } else {
                JSONObject json = new JSONObject();
                json.put("PJMCID", tempArray.getJSONObject(i).getString("PJMCID"));
                json.put("PJMC", tempArray.getJSONObject(i).getString("PJMC"));
                parts.get(tempArray.getJSONObject(i).getString("PARTNUMBER")).add(json);

            }
        }

        /**
         * 获取OE描述
         */
        JSONArray oemsArray = SpringManager.getBean(PartDao.class).queryOEMS(jsonArray1);
        Map<String, String> oemsMap = new HashMap();
        for (int i = 0; i < oemsArray.size(); i++) {
            oemsMap.put(oemsArray.getJSONObject(i).getString("PARTNUMBER"), oemsArray.getJSONObject(i).getString("OEMS"));
        }

        /**
         * 获取易错配件
         */
        Map<String, Object> easyErrorPJMC = SpringManager.getBean(PartDao.class).querypjmc_zptqr(jsonArray1).stream().collect(Collectors.toMap(object -> {
            JSONObject json = (JSONObject) object;
            return json.getString("PARTNUMBER");
        }, Function.identity(), (value1, value2) -> {
            return value1;
        }));

        /**
         * 方位图数据处理，JSONArray 转成 key,value
         */
        JSONArray partOrientationArray = SpringManager.getBean(PartDao.class).queryPartOrientation(jsonArray1);
        Map<String, Boolean> partOrientations;
        partOrientations = new HashMap();

        for (int i = 0; i < partOrientationArray.size(); i++) {
            partOrientations.put(partOrientationArray.getJSONObject(i).getString("PARTNAME_ZH"), true);
        }
        /**
         * 将方位图标识和标准配件存放到兆配接口数据中
         */
        for (int i = 0; i < jsonArray.size(); i++) {
            // 过滤partCode为空的数据
            if (jsonArray.getJSONObject(i).getString("partCode") == null) {
                jsonArray.getJSONObject(i).put("parts", new ArrayList<>());
                jsonArray.getJSONObject(i).put("OEMS", "");
                jsonArray.getJSONObject(i).put("ispartOrientation", false);
                jsonArray.getJSONObject(i).put("isEasyError", false);
                continue;
            }


            /**
             * 存放方位图数据
             */
            Boolean ispartOrientation;

            if (partOrientations.get(jsonArray.getJSONObject(i).getString("partName")) != null )
                ispartOrientation = true;
            else
                ispartOrientation = false;

            /**
             * 往接口的接口放对应的配件名称和方位图标识
             */

            if ( parts.get(jsonArray.getJSONObject(i).getString("partCode"))== null ) {
                List listPart = new ArrayList();
                jsonArray.getJSONObject(i).put("parts", listPart);
            } else {
                jsonArray.getJSONObject(i).put("parts", parts.get(jsonArray.getJSONObject(i).getString("partCode")));
            }

            jsonArray.getJSONObject(i).put("ispartOrientation", ispartOrientation);
            // 增加易错配件标识
            jsonArray.getJSONObject(i).put("isEasyError", easyErrorPJMC.get(
                    jsonArray.getJSONObject(i).getString("partCode")) == null ? false : true);

            /**
             * 放OE数据
             */
            if ( oemsMap.get(jsonArray.getJSONObject(i).getString("partCode")) == null )
                jsonArray.getJSONObject(i).put("OEMS", "");
            else jsonArray.getJSONObject(i).put("OEMS", oemsMap.get(jsonArray.getJSONObject(i).getString("partCode")));

        }

        return jsonArray;
    }

    public void partsAndHotPoints(SimpleRequest request) {
        JSONObject param = request.getJO();
        JSONArray parts = apiService.queryPartsWithSubGroup(param);
        JSONObject hotPoints = apiService.queryHotPointsWithSubGroup(param);
        for (Object o : parts) {
            JSONObject jsonObject = (JSONObject) o;
            String partCode = jsonObject.getString("partCode");
            if (partCode.equals(param.getString("partCode")));

        }
    }

    /**
     * 获取兆配的数据
     * @param partName
     * @param categoryName
     * @param param
     * @param PZCXID
     * @param QCCPMC
     * @param request
     * @return
     */
    public JSONObject getZPData(String partName, String categoryName, JSONObject param, String PZCXID, String QCCPMC, SimpleRequest request) {
        List<JSONObject> list = new ArrayList<>();
        JSONArray PJMCDZBZPArray = SpringManager.getBean(PartDao.class).queryPJMCDZB_ZP(categoryName);
        JSONObject clone;  //克隆存放的位置
        JSONArray jsonArray = new JSONArray();

        if (partName != null) {
            clone = cloneKeywords(param, partName);
            list.add(clone);
        }
        // 去除括号和括号的内容(标准配件名称)
        if (categoryName != null) {
            String s = categoryName.replaceAll("\\([^\\(^\\)]*\\)", "").replaceAll("\\([^\\(^\\)]*\\)", "");
            list.add(cloneKeywords(param, s));
        }

        for (Object o : PJMCDZBZPArray) {
            JSONObject json = (JSONObject)o;
            clone = cloneKeywords(param, json.getString("ZPPJMC"));
            list.add(clone);
        }

        /**
         * 输入文本 + 标准配件名称(去除括号) + 对照关系搜索兆配模糊查询接口
         */
        List<JSONObject> collect = list.parallelStream().map(jsonObject -> {
            return apiService.searchPartsByVinKeywords(jsonObject);
        }).collect(Collectors.toList());
        collect.stream().forEachOrdered(jsonObject -> {
            if (jsonObject.get("data") != null)
                jsonArray.addAll(jsonObject.getJSONObject("data").getJSONArray("items"));
        });
        /**
         * 返货结果去重
         */
        List<Object> items = deDuplication(jsonArray);
        clone = new JSONObject();
        JSONObject data  = new JSONObject();
        data.put("items", items);
        data.put("pagination", MapUtil.mapper("pageIndex", 1,"pageSize", 999, "totalCount", items.size()));
        clone.put("data",data );
        clone.put("statusCode", 200);
        if (!"200".equals(clone.getString("statusCode")) )
            throw new RuntimeException(clone.getString("errorMessage"));
        if (clone == null)
            clone = new JSONObject();
        param.put("PZCXID", PZCXID);
        param.put("QCCPMC", QCCPMC);
        SimpleRequest simpleRequest = new SimpleRequest();
        simpleRequest.setBody(param.toString());
        /**
         * 返回兆配返回数据加工
         */
        JSONArray combinationPartsData = combinationPartsData(param, clone.getJSONObject("data").getJSONArray("items"), simpleRequest);
        clone.getJSONObject("data").put("items", combinationPartsData);
        clone.put("statusCode", 200);
        saveEpcSearchLog(request, list, collect, clone);
        return clone;
    }

    private List deDuplication(JSONArray jsonArray) {
        List list = new ArrayList();
        for (Object o : jsonArray) {
            JSONObject jsonObject = (JSONObject) o;
            String id = jsonObject.getString("id");
            Boolean b = false;
            for (Object o1 : list) {
                JSONObject object = (JSONObject) o1;
                if ( object.getString("id").equals(id) )
                    b = true;
            }
            if (!b)
                list.add(o);
        }
        return list;
    }


    private void saveEpcSearchLog(SimpleRequest request, List<JSONObject> searchTexts, List<JSONObject> searchResult, JSONObject response) {
        MQUtil.publish("auto.parts.EpcSearchLog.save","异步保存日志",
                MapUtil.mapper("request", MapUtil.mapped(request.getJO()), "searchTexts", MapUtil.mapped(searchTexts),
                        "response", MapUtil.mapped(response), "searchResult", MapUtil.mapped(searchResult),"searchDate", new Date(),
                        "userId", request.getSession() != null ? request.getSession().getUserId() : null));
//        SimpleRequest param = new SimpleRequest();
//        param.setData( MapUtil.mapper("request", MapUtil.mapped(request.getJO()), "searchTexts", MapUtil.mapped(searchTexts),
//                        "response", MapUtil.mapped(response), "searchResult", MapUtil.mapped(searchResult),"searchData", new Date(),
//                        "userId", request.getSession() != null ? request.getSession().getUserId() : null));
//        SpringManager.getBean(EpcSearchLogService.class).save(param);
    }

    public JSONObject cloneKeywords(JSONObject param, String keyword){
        JSONObject clone = (JSONObject) param.clone();
        clone.put("keywords", keyword);
        return clone;
    }
}
